package choosers;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * @author Seabook
 * 
 * SOLUTION IS NOT TOO GOOD.
 *
 */
public class Choosers2 {

	public static void main(String[] args) {
		Choosers2 choosers = new Choosers2();
		String[] game1 = new String[] { "L 1 2", "R 2 0", "L X X" };
		String[] game2 = new String[] { "L 0 0" };
		String[] game3 = new String[] { "R 1 0", "L 1 0", "L X X" };
		String[] game4 = new String[] { "R 1 2", "R 1 2", "L X X" };
		System.out.println(choosers.length(game1, 0));
		System.out.println(choosers.length(game1, 2));
		System.out.println(choosers.length(game2, 1));
		System.out.println(choosers.length(game3, 0));
		System.out.println(choosers.length(game4, 0));
	}

	public int length(String[] game, int start) {
		List<Chooser> choosersInOrder = parseGameIntoChooser(game);
		int choosersNo = startGame(choosersInOrder, start);
		return choosersNo;
	}

	private int startGame(List<Chooser> choosersInOrder, int start) {
		// if there is no outlet, should return -1
		int count = 0;
		for (Chooser chooser : choosersInOrder) {
			if (!"X".equals(chooser.getNextLeftChooser())
					&& !"X".equals(chooser.getNextRightChooser())) {
				count++;
			}
		}

		if (count == choosersInOrder.size()) {
			return -1;
		}

		// Core Algorithm
		int chooserCount = 0;
		Chooser chooser = choosersInOrder.get(start);
		while (true) {
			int nextChooser = chooser.getNextChooser();
			chooser.changeOrientation();
			chooserCount++;
			if (nextChooser == -1) {
				break;
			}

			if (!chooser.isUniqueFingerPrint((int)Math.pow(2, choosersInOrder.size()))) {
				chooserCount = -1;
				break;
			}

			chooser = choosersInOrder.get(nextChooser);

		}

		return chooserCount;
	}

	private List<Chooser> parseGameIntoChooser(String[] game) {
		List<Chooser> choosers = new ArrayList<Chooser>(15);

		if (game == null || game.length == 0) {
			throw new RuntimeException("At least have one chooser in the game!");
		}

		if (game.length > 15) {
			throw new RuntimeException("Your choosers " + game.length
					+ " are surpassing the max Choosers No. 15! ");
		}

		for (String chooser : game) {
			String[] chooserSplits = chooser.split(" ");
			String initOrient = chooserSplits[0];
			String nextLeft = chooserSplits[1];
			String nextRight = chooserSplits[2];

			if (isValidChooser(initOrient, nextLeft, nextRight)) {
				Chooser vaildChooser = new Chooser(initOrient, nextLeft,
						nextRight);
				choosers.add(vaildChooser);
			}
		}

		return choosers;

	}

	private boolean isValidChooser(String initOrient, String nextLeft,
			String nextRight) {
		if (!"L".equals(initOrient) && !"R".equals(initOrient)) {
			throw new RuntimeException("Chooser is Invalid with: " + initOrient);
		}

		// Omit other checks, assume all the data are valid.
		// Will do the check later.
		// TODO

		return true;
	}
}

class Chooser {
	private String initOrientation;
	private String nextLeftChooser;
	private String nextRightChooser;

	private String initInternalState;
	private int internalCount;

	public Chooser() {
		this.initInternalState = initOrientation + nextLeftChooser
				+ nextRightChooser;
	}

	public Chooser(String initOrientation, String nextLeftChooser,
			String nextRightChooser) {
		this.initOrientation = initOrientation;
		this.nextLeftChooser = nextLeftChooser;
		this.nextRightChooser = nextRightChooser;

		this.initInternalState = initOrientation + nextLeftChooser
				+ nextRightChooser;
	}

	public boolean isUniqueFingerPrint(int count) {
		if (initInternalState.equals(getCurrentInternalState())) {
			internalCount++;
		}

		if (internalCount == count)
			return false;

		return true;
	}

	public String getCurrentInternalState() {
		return initOrientation + nextLeftChooser + nextRightChooser;
	}

	public int getNextChooser() {
		String nextChooser = null;
		if ("L".equalsIgnoreCase(initOrientation)) {
			nextChooser = nextLeftChooser;
		} else
			nextChooser = nextRightChooser;

		if ("X".equals(nextChooser)) {
			return -1;
		} else
			return Integer.valueOf(nextChooser);
	}

	public void changeOrientation() {
		if ("L".equalsIgnoreCase(initOrientation)) {
			initOrientation = "R";
		} else
			initOrientation = "L";
	}

	public String getInitOrientation() {
		return initOrientation;
	}

	public void setInitOrientation(String initOrientation) {
		this.initOrientation = initOrientation;
	}

	public String getNextLeftChooser() {
		return nextLeftChooser;
	}

	public void setNextLeftChooser(String nextLeftChooser) {
		this.nextLeftChooser = nextLeftChooser;
	}

	public String getNextRightChooser() {
		return nextRightChooser;
	}
}
